﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Taxonomy;
using System.Globalization;

namespace Ko2.Portal
{

    public static class MetadataHelper
    {
        public static TermSet FindTermSet(string parSiteUrl, String parNameTermSet)
        {
            TermSet ret = null;
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(parSiteUrl))
                {
                    TaxonomySession mSess = new TaxonomySession(site);
                    // Stores
                    foreach (TermStore mStore in mSess.TermStores)
                    {
                        // Groups
                        foreach (Group mGroup in mStore.Groups)
                        {
                            // TermSets == NameLib
                            foreach (TermSet mSet in mGroup.TermSets)
                            {
                                if (mSet.Name == parNameTermSet)
                                {
                                    ret = mSet;
                                    break;
                                }
                            } // TermSet
                        } // Groups
                    } // Stores
                } // using site
            });
            return ret;
        }
        public static bool ExistTermSet(string parSiteUrl, String parNameTermSet)
        {
            bool ret = false;
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(parSiteUrl))
                {
                    ret = ExistTermSet(site, parNameTermSet);
                }
            });
            return ret;
        }
        public static bool ExistTermSet(SPSite site, String parNameTermSet)
        {
            bool ret = false;
            TaxonomySession mSess = new TaxonomySession(site);
            // Stores
            foreach (TermStore mStore in mSess.TermStores)
            {
                // Groups
                foreach (Group mGroup in mStore.Groups)
                {
                    // TermSets == NameLib
                    foreach (TermSet mSet in mGroup.TermSets)
                    {
                        if (mSet.Name == parNameTermSet)
                        {
                            ret = true;
                            break;
                        }
                    } // TermSet
                } // Groups
            } // Stores
            return ret;
        }

        public static Term FindItem(string parSiteUrl, String parNameLib, String parID, int lcid)
        {
            Term ret = null;
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(parSiteUrl))
                {
                    TaxonomySession mSess = new TaxonomySession(site);
                    // Stores
                    foreach (TermStore mStore in mSess.TermStores)
                    {
                        // Groups
                        foreach (Group mGroup in mStore.Groups)
                        {
                            // TermSets == NameLib
                            foreach (TermSet mSet in mGroup.TermSets)
                            {
                                if (mSet.Name == parNameLib)
                                {
                                    // Term == Id
                                    foreach (Term mTerm in mSet.Terms)
                                    {
                                        if (mTerm.GetDescription(lcid).Trim() == parID)
                                        {
                                            ret = mTerm;
                                            break;
                                        }
                                    } // Term
                                }
                            } // TermSet
                        } // Groups
                    } // Stores
                } // using site
            });
            return ret;
        }
        public static Term FindItemByName(string parSiteUrl, String parNameLib, String parName)
        {
            return FindItemByName(parSiteUrl, parNameLib, parName, CultureInfo.CurrentCulture.LCID);
        }
        public static Term FindItemByName(string parSiteUrl, String parNameLib, String parName, int lcid)
        {
            Term ret = null;
            string str = parName.ToLower();
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(parSiteUrl))
                {
                    TaxonomySession mSess = new TaxonomySession(site);
                    // Stores
                    foreach (TermStore mStore in mSess.TermStores)
                    {
                        // Groups
                        foreach (Group mGroup in mStore.Groups)
                        {
                            // TermSets == NameLib
                            foreach (TermSet mSet in mGroup.TermSets)
                            {
                                if (mSet.Name == parNameLib)
                                {
                                    // Term == Id
                                    foreach (Term mTerm in mSet.Terms)
                                    {
                                        if (mTerm.Name.Trim().ToLower() == str)
                                        {
                                            ret = mTerm;
                                            break;
                                        }
                                    } // Term
                                }
                            } // TermSet
                        } // Groups
                    } // Stores
                } // using site
            });
            return ret;
        }
        public static bool ExistItem(string parSiteUrl, String parNameLib, String parID, int lcid)
        {
            bool ret = false;
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(parSiteUrl))
                {
                    ret = ExistItem(site, parNameLib, parID, lcid);
                }
            });
            return ret;
        }
        public static bool ExistItem(SPSite site, String parNameLib, String parID, int lcid)
        {
            bool ret = false;
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                TaxonomySession mSess = new TaxonomySession(site);
                // Stores
                foreach (TermStore mStore in mSess.TermStores)
                {
                    // Groups
                    foreach (Group mGroup in mStore.Groups)
                    {
                        // TermSets == NameLib
                        foreach (TermSet mSet in mGroup.TermSets)
                        {
                            if (mSet.Name == parNameLib)
                            {
                                // Term == Id
                                foreach (Term mTerm in mSet.Terms)
                                {
                                    if (mTerm.GetDescription(lcid).Trim() == parID)
                                    {
                                        ret = true;
                                        break;
                                    }
                                } // Term
                            }
                        } // TermSet
                    } // Groups
                } // Stores
            });
            return ret;
        }

        public static Term inExistsLib(string parSiteUrl, String parNameLib, String parID, int lcid)
        {
            Term mRet = null;
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(parSiteUrl))
                {
                    TaxonomySession mSess = new TaxonomySession(site);
                    foreach (TermStore mStore in mSess.TermStores)
                    {
                        foreach (Group mGroup in mStore.Groups)
                        {
                            foreach (TermSet mSet in mGroup.TermSets)
                            {
                                if (mSet.Name == parNameLib)
                                {
                                    foreach (Term mTerm in mSet.Terms)
                                    {
                                        if (mTerm.GetDescription(lcid).Trim() == parID)
                                        {
                                            mRet = mTerm;
                                        }
                                        foreach (Term mTerm1 in mTerm.Terms)
                                        {
                                            if (mTerm1.GetDescription(lcid).Trim() == parID)
                                            {
                                                mRet = mTerm1;
                                            }
                                            foreach (Term mTerm2 in mTerm1.Terms)
                                            {
                                                if (mTerm2.GetDescription(lcid).Trim() == parID)
                                                {
                                                    mRet = mTerm2;
                                                }
                                            } // foreach (Term mTerm2 in mTerm1.Terms)
                                        } // foreach (Term mTerm1 in mTerm.Terms)
                                    } // foreach (Term mTerm in mSet.Terms)
                                } // if (mSet.Name == mNameLib)
                            } // foreach (TermSet mSet in mGroup.TermSets)
                        } // foreach (Group mGroup in mStore.Groups)
                    } // foreach (TermStore mStore in mSess.TermStores)
                } // Site
            });
            return mRet;
        }

        public static void SetFieldValueTerm(SPListItem li, string fieldName, Term term)
        {
            SPField termField = li.Fields[fieldName];

            TaxonomyFieldValueCollection tfvc = new TaxonomyFieldValueCollection(termField);
            tfvc.Add(new TaxonomyFieldValue(termField));
            li[fieldName] = tfvc;

            TaxonomyField taxonomyField = termField as TaxonomyField;
            if (taxonomyField != null)
            {
                taxonomyField.SetFieldValue(li, term);
            }
        }

        public static string[] GetTermValuesStrArray(ref SPSite site, ref SPField field, int lcid)
        {
            string[] terms = null;
            TaxonomyFieldValueCollection tfvc = new TaxonomyFieldValueCollection(field);
            TaxonomyField taxonomyField = field as TaxonomyField;

            TaxonomySession session = new TaxonomySession(site);
            if (session == null)
                return terms;
            TermStore termStore = session.TermStores[taxonomyField.SspId];
            if(termStore == null)
                return terms;
            TermSet termSet = termStore.GetTermSet(taxonomyField.TermSetId);
            if (termSet == null)
                return terms;

            terms = termSet.GetAllTerms()
                .Select(t => String.Concat(
                t.GetDefaultLabel(lcid),
                TaxonomyField.TaxonomyGuidLabelDelimiter,
                t.Id))
                .ToArray();

            return terms;
        }

        public static TaxonomyFieldValueCollection GetTermValues(ref SPSite site, ref SPField field, int lcid)
        {
            TaxonomyFieldValueCollection ret = null;
            string[] terms = GetTermValuesStrArray(ref site, ref field, lcid);
            if (terms == null)
                return ret;
            ret = new TaxonomyFieldValueCollection(field);
            ret.PopulateFromLabelGuidPairs(String.Join(
                TaxonomyField.TaxonomyMultipleTermDelimiter.ToString(), terms));
            return ret;
        }

    }

}
